package com.xuelang.pipeline.artifact.app.resource.impl;

import cn.hutool.core.util.StrUtil;
import com.xuelang.pipeline.artifact.app.harborv2.ProjectService;
import com.xuelang.pipeline.artifact.app.harborv2.WebhookService;
import com.xuelang.pipeline.artifact.app.harborv2.enums.HarborWebhookEventTypeEnum;
import com.xuelang.pipeline.artifact.app.harborv2.enums.WebhookTargetTypeEnum;
import com.xuelang.pipeline.artifact.app.harborv2.request.CreateProjectRequest;
import com.xuelang.pipeline.artifact.app.harborv2.request.CreateWebhookPolicyRequest;
import com.xuelang.pipeline.artifact.app.harborv2.request.ListWebhookPolicyQuery;
import com.xuelang.pipeline.artifact.app.harborv2.response.ListWebhookPolicyResponse;
import com.xuelang.pipeline.artifact.app.harborv2.xo.ProjectMetadata;
import com.xuelang.pipeline.artifact.app.harborv2.xo.WebhookTargetObject;
import com.xuelang.pipeline.artifact.app.nexus3v1.RepositoryManagementService;
import com.xuelang.pipeline.artifact.app.nexus3v1.SecurityRoleService;
import com.xuelang.pipeline.artifact.app.nexus3v1.WebhookRepositoryCapabilityService;
import com.xuelang.pipeline.artifact.app.nexus3v1.enums.Nexus3RepositoryTypeEnum;
import com.xuelang.pipeline.artifact.app.nexus3v1.request.*;
import com.xuelang.pipeline.artifact.app.nexus3v1.response.CreateRoleResponse;
import com.xuelang.pipeline.artifact.app.nexus3v1.response.CreateWebhookRepositoryResponse;
import com.xuelang.pipeline.artifact.app.nexus3v1.xo.*;
import com.xuelang.pipeline.artifact.app.resource.InstanceRepositoryService;
import com.xuelang.pipeline.artifact.app.resource.InstanceUserService;
import com.xuelang.pipeline.artifact.client.common.constant.ArtifactConstant;
import com.xuelang.pipeline.artifact.client.common.constant.Constant;
import com.xuelang.pipeline.artifact.client.common.exception.BizException;
import com.xuelang.pipeline.artifact.client.resource.dto.ArtifactProxyQuery;
import com.xuelang.pipeline.artifact.client.resource.dto.ArtifactUserQuery;
import com.xuelang.pipeline.artifact.client.resource.enums.ArtifactToolEnum;
import com.xuelang.pipeline.artifact.domain.resource.ArtifactAttribute;
import com.xuelang.pipeline.artifact.domain.resource.ArtifactProxy;
import com.xuelang.pipeline.artifact.domain.resource.ArtifactTool;
import com.xuelang.pipeline.artifact.domain.resource.ArtifactUser;
import com.xuelang.pipeline.artifact.domain.resource.service.ArtifactAttributeDomainService;
import com.xuelang.pipeline.artifact.domain.resource.service.ArtifactProxyDomainService;
import com.xuelang.pipeline.artifact.domain.resource.service.ArtifactUserDomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author xiwen.zxg
 * @since 2024/7/11
 */
@Service
public class InstanceRepositoryServiceImpl implements InstanceRepositoryService {

    @Autowired
    InstanceUserService instanceUserService;
    @Autowired
    WebhookRepositoryCapabilityService webhookRepositoryCapabilityService;
    @Autowired
    RepositoryManagementService repositoryManagementService;
    @Autowired
    ArtifactUserDomainService artifactUserDomainService;
    @Autowired
    SecurityRoleService securityRoleService;
    @Autowired
    ProjectService projectService;
    @Autowired
    WebhookService webhookService;
    @Autowired
    ArtifactAttributeDomainService artifactAttributeDomainService;
    @Autowired
    ArtifactProxyDomainService artifactProxyDomainService;
    @Value("${feign.rpc.nexus3V1WebhookRepositoryLocalService}")
    private String nexus3V1WebhookRepositoryLocalService;
    @Value("${feign.rpc.harborV2WebhookRepositoryLocalService}")
    private String harborV2WebhookRepositoryLocalService;

    @Override
    public void createRepository(ArtifactToolEnum.ArtifactTypeEnum artifactType, String repositoryName, String artifactUuid) {

        if (true) {
            createRepositoryWithGroupAndHosted(artifactType, repositoryName, artifactUuid);
            return;
        }

        switch(artifactType) {
            case MAVEN:
                CreateMavenHostedRequest mavenHostedRequest =  new CreateMavenHostedRequest();
                mavenHostedRequest.setName(repositoryName);
                mavenHostedRequest.setOnline(true);
                mavenHostedRequest.setStorage(HostedStorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).writePolicy("allow").build());
                mavenHostedRequest.setMaven(MavenAttributes.builder().versionPolicy(ArtifactToolEnum.MavenStorageStrategyEnum.MIXED.name()).layoutPolicy("PERMISSIVE").build());
                ApiResponseXO<Void> mavenHostedRepositoryResponse =  repositoryManagementService.createMavenHostedRepository(mavenHostedRequest);
                if (mavenHostedRepositoryResponse.isSuccess()
                        && createNexusUserRolePrivilege(ArtifactConstant.NEXUS3_PRIVILEGES_PREFIX_MAVEN2, repositoryName, null, null)
                        && createNexusRepositoryCapability(repositoryName, artifactUuid)) {
                    break;
                }
                throw new BizException(mavenHostedRepositoryResponse.getMessage());
            case NPM:
                CreateNpmHostedRequest npmHostedRequest =  new CreateNpmHostedRequest();
                npmHostedRequest.setName(repositoryName);
                npmHostedRequest.setOnline(true);
                npmHostedRequest.setStorage(HostedStorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).writePolicy("allow").build());
                ApiResponseXO<Void> npmHostedRepositoryResponse = repositoryManagementService.createNpmHostedRepository(npmHostedRequest);

                if (npmHostedRepositoryResponse.isSuccess()
                        && createNexusUserRolePrivilege(ArtifactConstant.NEXUS3_PRIVILEGES_PREFIX_NPM, repositoryName, null, null)
                        && createNexusRepositoryCapability(repositoryName, artifactUuid)) {
                    break;
                }
                throw new BizException(npmHostedRepositoryResponse.getMessage());
            case GENERIC:
                // TODO: 通用仓库-815之后版本
                CreateRawHostedRequest rawHostedRequest =  new CreateRawHostedRequest();
                rawHostedRequest.setName(repositoryName);
                rawHostedRequest.setOnline(true);
                rawHostedRequest.setStorage(HostedStorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).writePolicy("allow").build());
                ApiResponseXO<Void> rawHostedRepositoryResponse = repositoryManagementService.createRawHostedRepository(rawHostedRequest);

                if (rawHostedRepositoryResponse.isSuccess()
                        && createNexusUserRolePrivilege(ArtifactConstant.NEXUS3_PRIVILEGES_PREFIX_RAW, repositoryName, null, null)
                        && createNexusRepositoryCapability(repositoryName, artifactUuid)) {
                    break;
                }
                throw new BizException(rawHostedRepositoryResponse.getMessage());
            case DOCKER:
                CreateProjectRequest createProjectRequest = new CreateProjectRequest();
                createProjectRequest.setProjectName(repositoryName);
                createProjectRequest.setMetadata(ProjectMetadata.builder().requestPublic("false").build());
                createProjectRequest.setStorageLimit(-1L);
                ApiResponseXO<Void> createProjectResponse = projectService.createProject(createProjectRequest);
                if (createProjectResponse.isSuccess()
                        && createDockerRepositoryWebhook(repositoryName, artifactUuid)) {
                    break;
                }
                throw new BizException(createProjectResponse.getMessage());
            default:
                throw new BizException("not support this type" + artifactType);
        }
    }

    @Override
    public void createRepositoryWithGroupAndHosted(ArtifactToolEnum.ArtifactTypeEnum artifactType, String repositoryName, String artifactUuid) {
        String instanceRepositoryName = repositoryName;
        String hostedInstanceRepositoryName = (Nexus3RepositoryTypeEnum.HOSTED.name() + Constant.DEFAULT_MIDDLE_SEPARATOR + instanceRepositoryName).toLowerCase();
        String groupInstanceRepositoryName = (Nexus3RepositoryTypeEnum.GROUP.name() + Constant.DEFAULT_MIDDLE_SEPARATOR + instanceRepositoryName).toLowerCase();
        switch(artifactType) {
            case MAVEN:
                // 创建hosted仓库，hosted仓库名称=实例仓库名称+"-hosted"
                CreateMavenHostedRequest mavenHostedRequest =  new CreateMavenHostedRequest();
                mavenHostedRequest.setName(hostedInstanceRepositoryName);
                mavenHostedRequest.setOnline(true);
                mavenHostedRequest.setStorage(HostedStorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).writePolicy("allow").build());
                mavenHostedRequest.setMaven(MavenAttributes.builder().versionPolicy(ArtifactToolEnum.MavenStorageStrategyEnum.MIXED.name()).layoutPolicy("PERMISSIVE").build());
                ApiResponseXO<Void> mavenHostedRepositoryResponse = repositoryManagementService.createMavenHostedRepository(mavenHostedRequest);

                if(mavenHostedRepositoryResponse.isSuccess()) {
                    // 创建group仓库，使用实例仓库名称
                    CreateMavenGroupRequest mavenGroupRequest = new CreateMavenGroupRequest();
                    mavenGroupRequest.setName(groupInstanceRepositoryName);
                    mavenGroupRequest.setOnline(true);
                    mavenGroupRequest.setStorage(StorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).build());
                    mavenGroupRequest.setGroup(GroupAttributes.builder().memberNames(Collections.singletonList(mavenHostedRequest.getName())).build());
                    ApiResponseXO<Void> mavenGroupRepositoryResponse = repositoryManagementService.createMavenGroupRepository(mavenGroupRequest);

                    if (mavenGroupRepositoryResponse.isSuccess()
                            && createNexusUserRolePrivilege(ArtifactConstant.NEXUS3_PRIVILEGES_PREFIX_MAVEN2, instanceRepositoryName, hostedInstanceRepositoryName, groupInstanceRepositoryName)
                            && createNexusRepositoryCapability(hostedInstanceRepositoryName, artifactUuid)) {
                        break;
                    }
                }
                throw new BizException(mavenHostedRepositoryResponse.getMessage());
            case NPM:
                CreateNpmHostedRequest npmHostedRequest =  new CreateNpmHostedRequest();
                npmHostedRequest.setName(hostedInstanceRepositoryName);
                npmHostedRequest.setOnline(true);
                npmHostedRequest.setStorage(HostedStorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).writePolicy("allow").build());
                ApiResponseXO<Void> npmHostedRepositoryResponse = repositoryManagementService.createNpmHostedRepository(npmHostedRequest);
                if (npmHostedRepositoryResponse.isSuccess()) {
                    // 创建group仓库，使用实例仓库名称
                    CreateNpmGroupRequest npmGroupRequest = new CreateNpmGroupRequest();
                    npmGroupRequest.setName(groupInstanceRepositoryName);
                    npmGroupRequest.setOnline(true);
                    npmGroupRequest.setStorage(StorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).build());
                    npmGroupRequest.setGroup(GroupDeployAttributes.builder().memberNames(Collections.singletonList(npmHostedRequest.getName())).build());
                    ApiResponseXO<Void> npmGroupRepositoryResponse = repositoryManagementService.createNpmGroupRepository(npmGroupRequest);

                    if (npmGroupRepositoryResponse.isSuccess()
                            && createNexusUserRolePrivilege(ArtifactConstant.NEXUS3_PRIVILEGES_PREFIX_NPM, instanceRepositoryName, hostedInstanceRepositoryName, groupInstanceRepositoryName)
                            && createNexusRepositoryCapability(hostedInstanceRepositoryName, artifactUuid)) {
                        break;
                    }
                }
                throw new BizException(npmHostedRepositoryResponse.getMessage());
            case GENERIC:
                // TODO: 通用仓库-815之后版本
                CreateRawHostedRequest rawHostedRequest =  new CreateRawHostedRequest();
                rawHostedRequest.setName(instanceRepositoryName);
                rawHostedRequest.setOnline(true);
                rawHostedRequest.setStorage(HostedStorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).writePolicy("allow").build());
                ApiResponseXO<Void> rawHostedRepositoryResponse = repositoryManagementService.createRawHostedRepository(rawHostedRequest);

                if (rawHostedRepositoryResponse.isSuccess()
                        && createNexusUserRolePrivilege(ArtifactConstant.NEXUS3_PRIVILEGES_PREFIX_RAW, instanceRepositoryName, null, null)
                        && createNexusRepositoryCapability(instanceRepositoryName, artifactUuid)) {
                    break;
                }
                throw new BizException(rawHostedRepositoryResponse.getMessage());
            case DOCKER:
                // 采用harbor仓库实现docker镜像仓库
                CreateProjectRequest createProjectRequest = new CreateProjectRequest();
                createProjectRequest.setProjectName(instanceRepositoryName);
                createProjectRequest.setMetadata(ProjectMetadata.builder().requestPublic("false").build());
                createProjectRequest.setStorageLimit(-1L);
                ApiResponseXO<Void> createProjectResponse = projectService.createProject(createProjectRequest);
                if (createProjectResponse.isSuccess()
                        && createDockerRepositoryWebhook(instanceRepositoryName, artifactUuid)) {
                    break;
                }
                throw new BizException(createProjectResponse.getMessage());
            default:
                throw new BizException("not support this type" + artifactType);
        }
    }

    /**
     * 创建Docker项目的Webhook
     *
     * @param repositoryName
     * @param artifactUuid
     * @return
     */
    private boolean createDockerRepositoryWebhook(String repositoryName, String artifactUuid) {
        CreateWebhookPolicyRequest createWebhookPolicyRequest = new CreateWebhookPolicyRequest();
        createWebhookPolicyRequest.setEnabled(true);
        createWebhookPolicyRequest.setName(ArtifactConstant.HARBOR_WEBHOOK_NAME_PREFIX + repositoryName);
        createWebhookPolicyRequest.setEventTypes(HarborWebhookEventTypeEnum.toList());

        WebhookTargetObject target = new WebhookTargetObject();
        target.setType(WebhookTargetTypeEnum.http.name());
        target.setAddress(harborV2WebhookRepositoryLocalService);
        target.setSkipCERTVerify(true);
        target.setPayloadFormat(ArtifactConstant.HARBOR_WEBHOOK_TARGET_PAYLOAD_FORMAT);
        createWebhookPolicyRequest.setTargets(Collections.singletonList(target));
        ApiResponseXO<Void> projectWebhook = webhookService.createProjectWebhook(repositoryName, createWebhookPolicyRequest);
        ApiResponseXO<List<ListWebhookPolicyResponse>> listApiResponseXO = webhookService.listProjectWebhook(repositoryName, new ListWebhookPolicyQuery());
        if (projectWebhook.isSuccess() && listApiResponseXO.isSuccess()) {
            Optional.ofNullable(listApiResponseXO.getData()).ifPresent(list -> {
                if (!list.isEmpty()) {
                    artifactAttributeDomainService.updateWebhookInfo(artifactUuid, list.get(0).getName(), String.valueOf(list.get(0).getId()));
                }
            });
        }
        return true;
    }

    @Override
    public void deleteRepository(ArtifactTool artifactTool, ArtifactAttribute artifactAttribute) {
        ArtifactToolEnum.ArtifactTypeEnum artifactType = ArtifactToolEnum.ArtifactTypeEnum.getByKey(artifactTool.getArtifactType());
        String repositoryName = artifactTool.getInstanceRepositoryName();
        String artifactUuid = artifactTool.getUuid();
        String webhookId = artifactAttribute.getWebhookId();
        switch(artifactType) {
            case MAVEN:
            case NPM:
                // 删除hosted仓库
                String hostedRepositoryName =(Nexus3RepositoryTypeEnum.HOSTED.name() + Constant.DEFAULT_MIDDLE_SEPARATOR + repositoryName).toLowerCase();
                repositoryManagementService.deleteRepositoryOfAnyFormat(hostedRepositoryName);
                // 查询并删除代理实例仓库
                Optional.ofNullable(artifactProxyDomainService.list(ArtifactProxyQuery.builder().groupArtifactUuid(artifactUuid).artifactType(artifactType.name()).build()))
                        .ifPresent(list -> list.forEach(artifactProxy -> repositoryManagementService.deleteRepositoryOfAnyFormat(artifactProxy.getProxyInstanceRepoName())));
                // 删除数据库中代理仓库关联
                artifactProxyDomainService.deleteByGroupArtifactUuid(artifactUuid);
                // 删除group仓库
                String groupRepositoryName =(Nexus3RepositoryTypeEnum.GROUP.name() + Constant.DEFAULT_MIDDLE_SEPARATOR + repositoryName).toLowerCase();
                ApiResponseXO<Void> deleteGroupRepositoryResponse = repositoryManagementService.deleteRepositoryOfAnyFormat(groupRepositoryName);
                if (deleteGroupRepositoryResponse.isSuccess()
                        && deleteNexusUserRolePrivilege(repositoryName)
                        && deleteUserInstanceAndInfo(artifactType, artifactUuid)
                        && removeRepositoryCapability(artifactUuid, webhookId)) {
                    break;
                }
                throw new BizException(deleteGroupRepositoryResponse.getMessage());
            case GENERIC:
                // 查询并删除代理实例仓库
                Optional.ofNullable(artifactProxyDomainService.list(ArtifactProxyQuery.builder().groupArtifactUuid(artifactUuid).artifactType(artifactType.name()).build()))
                        .ifPresent(list -> list.forEach(artifactProxy -> repositoryManagementService.deleteRepositoryOfAnyFormat(artifactProxy.getProxyInstanceRepoName())));
                // 删除数据库中代理仓库关联
                artifactProxyDomainService.deleteByGroupArtifactUuid(artifactUuid);
                // 删除实例仓库
                ApiResponseXO<Void> deleteInstanceRepositoryResponse = repositoryManagementService.deleteRepositoryOfAnyFormat(repositoryName);
                if (deleteInstanceRepositoryResponse.isSuccess()
                        && deleteNexusUserRolePrivilege(repositoryName)
                        && deleteUserInstanceAndInfo(artifactType, artifactUuid)
                        && removeRepositoryCapability(artifactUuid, webhookId)) {
                    break;
                }
                throw new BizException(deleteInstanceRepositoryResponse.getMessage());
            case DOCKER:
                ApiResponseXO<Void> deleteProjectResponse = projectService.deleteProject(repositoryName);
                if (deleteProjectResponse.isSuccess()
                        && deleteUserInstanceAndInfo(artifactType, artifactUuid)
                        && removeDockerRepositoryWebhook(repositoryName)) {
                    break;
                }
                throw new BizException(deleteProjectResponse.getMessage());
            default:
                throw new BizException("not support this type" + artifactType);
        }
    }

    /**
     * 删除仓库能力
     *
     * @param repositoryName
     * @return
     */
    private boolean removeDockerRepositoryWebhook(String repositoryName) {
        // harbor的Webhook是挂在项目下的，因此删除项目会自动级联删除该项目下的webhook，不需要手动删除，此处只做tips
        return true;
    }

    @Override
    public void listRespsitory() {

    }

    @Override
    public void createProxyRepository(ArtifactToolEnum.ArtifactTypeEnum proxyArtifactType, ArtifactProxy artifactProxy, List<String> proxyInstanceRepoNameList) {
        String instanceRepositoryName = artifactProxy.getGroupInstanceRepoName();
        String hostedInstanceRepositoryName = (Nexus3RepositoryTypeEnum.HOSTED.name() + Constant.DEFAULT_MIDDLE_SEPARATOR + instanceRepositoryName).toLowerCase();
        String groupInstanceRepositoryName = (Nexus3RepositoryTypeEnum.GROUP.name() + Constant.DEFAULT_MIDDLE_SEPARATOR + instanceRepositoryName).toLowerCase();
        String proxyInstanceRepositoryName = (Nexus3RepositoryTypeEnum.PROXY.name() + Constant.DEFAULT_MIDDLE_SEPARATOR + instanceRepositoryName + Constant.DEFAULT_MIDDLE_SEPARATOR + artifactProxy.getSourceArtifactCode()).toLowerCase();
        proxyInstanceRepoNameList = (proxyInstanceRepoNameList == null ? new ArrayList<>() : proxyInstanceRepoNameList);
        // 增加本仓库的默认hosted仓库
        proxyInstanceRepoNameList.add(hostedInstanceRepositoryName);
        switch(proxyArtifactType) {
            case MAVEN:
                /*创建代理仓库代码*/
                // 创建Proxy仓库，Proxy仓库名称=实例仓库名称+代理仓库artifactCode+"-artifactProxy"
                CreateMavenProxyRequest mavenProxyRequest = new CreateMavenProxyRequest();
                mavenProxyRequest.setName(proxyInstanceRepositoryName);
                mavenProxyRequest.setOnline(true);
                mavenProxyRequest.setMaven(MavenAttributes.builder().versionPolicy(ArtifactToolEnum.MavenStorageStrategyEnum.MIXED.name()).layoutPolicy("PERMISSIVE").build());
                mavenProxyRequest.setProxy(ProxyAttributes.builder().remoteUrl(artifactProxy.getSourceArtifactServerAddr()).contentMaxAge(-1).metadataMaxAge(1440).build());
                mavenProxyRequest.setHttpClient(HTTPClientAttributesWithPreemptiveAuth.builder()
                        .blocked(false)
                        .autoBlock(true)
                        .authentication(HTTPClientConnectionAuthenticationAttributesWithPreemptive.builder()
                                .type("username")
                                .username(artifactProxy.getSourceUserName())
                                .password(artifactProxy.getSourcePassword())
                                .build())
                        .build());
                mavenProxyRequest.setStorage(StorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).build());
                mavenProxyRequest.setNegativeCache(NegativeCacheAttributes.builder().enabled(true).timeToLive(1440).build());
                ApiResponseXO<Void> mavenProxyRepositoryResponse = repositoryManagementService.createMavenProxyRepository(mavenProxyRequest);
                if(mavenProxyRepositoryResponse.isSuccess()) {
                    // 更新group仓库
                    CreateMavenGroupRequest updateMavenGroupRequest = new CreateMavenGroupRequest();
                    updateMavenGroupRequest.setName(groupInstanceRepositoryName);
                    updateMavenGroupRequest.setOnline(true);
                    updateMavenGroupRequest.setStorage(StorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).build());
                    updateMavenGroupRequest.setGroup(GroupAttributes.builder().memberNames(proxyInstanceRepoNameList).build());
                    ApiResponseXO<Void> updateMavenGroupRepositoryResponse = repositoryManagementService.updateMavenGroupRepository(groupInstanceRepositoryName, updateMavenGroupRequest);

                    if (updateMavenGroupRepositoryResponse.isSuccess()) {
                        break;
                    }
                }

                throw new BizException(mavenProxyRepositoryResponse.getMessage());
            case NPM:
                /*创建代理仓库代码*/
                // 创建Proxy仓库，Proxy仓库名称=实例仓库名称+代理仓库artifactCode+"-artifactProxy"
                CreateNpmProxyRequest npmProxyRequest = new CreateNpmProxyRequest();
                npmProxyRequest.setName(proxyInstanceRepositoryName);
                npmProxyRequest.setOnline(true);
                npmProxyRequest.setProxy(ProxyAttributes.builder().remoteUrl(artifactProxy.getSourceArtifactServerAddr()).contentMaxAge(-1).metadataMaxAge(1440).build());
                npmProxyRequest.setHttpClient(HTTPClientAttributes.builder()
                        .blocked(false)
                        .autoBlock(true)
                        .authentication(HTTPClientConnectionAuthenticationAttributes.builder()
                                .type("username")
                                .username(artifactProxy.getSourceUserName())
                                .password(artifactProxy.getSourcePassword())
                                .build())
                        .build());
                npmProxyRequest.setStorage(StorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).build());
                npmProxyRequest.setNegativeCache(NegativeCacheAttributes.builder().enabled(true).timeToLive(1440).build());
                ApiResponseXO<Void> npmProxyRepositoryResponse = repositoryManagementService.createNpmProxyRepository(npmProxyRequest);
                if(npmProxyRepositoryResponse.isSuccess()) {
                    // 更新group仓库
                    CreateNpmGroupRequest updateNpmGroupRequest = new CreateNpmGroupRequest();
                    updateNpmGroupRequest.setName(groupInstanceRepositoryName);
                    updateNpmGroupRequest.setOnline(true);
                    updateNpmGroupRequest.setStorage(StorageAttributes.builder().blobStoreName("default").strictContentTypeValidation(true).build());
                    updateNpmGroupRequest.setGroup(GroupDeployAttributes.builder().memberNames(proxyInstanceRepoNameList).build());
                    ApiResponseXO<Void> updateNpmGroupRepositoryResponse = repositoryManagementService.updateNpmGroupRepository(groupInstanceRepositoryName, updateNpmGroupRequest);

                    if (updateNpmGroupRepositoryResponse.isSuccess()) {
                        break;
                    }
                }

                throw new BizException(npmProxyRepositoryResponse.getMessage());
            case GENERIC:
                // 通用仓库无代理仓库功能
            case DOCKER:
                // Docker仓库无代理仓库功能
            default:
                throw new BizException("not support this type" + proxyArtifactType);
        }
    }


    @Override
    public void deleteProxyRepository(ArtifactToolEnum.ArtifactTypeEnum artifactType, String proxyInstanceRepoName) {
        switch(artifactType) {
            case MAVEN:
            case NPM:
            case GENERIC:
                // 删除代理仓库，理论上需要同时删除分组仓库中该代理仓库的关联，但是Nexus3当删除代理仓库时，会自动删除关联关系，因此此处不手动删除分组仓库的关联关系
                ApiResponseXO<Void> deleteRepositoryResponse = repositoryManagementService.deleteRepositoryOfAnyFormat(proxyInstanceRepoName);
                if (deleteRepositoryResponse.isSuccess()) {
                    break;
                }
                throw new BizException(deleteRepositoryResponse.getMessage());
            case DOCKER:
            default:
                throw new BizException("not support this type" + artifactType);
        }
    }
    /**
     * 删除Nexus3用户角色权限
     *
     * @param repositoryName
     * @return
     */
    private boolean deleteNexusUserRolePrivilege(String repositoryName) {
        // 删除仓库角色-管理员
        ApiResponseXO<Void> managerRoleResponse = securityRoleService.deleteRole(ArtifactConstant.ROLE_PREFIX_MANAGER + repositoryName);
        // 删除仓库角色-开发人员
        ApiResponseXO<Void> developerRoleResponse = securityRoleService.deleteRole(ArtifactConstant.ROLE_PREFIX_DEVELOPER + repositoryName);
        // 删除仓库角色-普通用户
        ApiResponseXO<Void> userRoleResponse = securityRoleService.deleteRole(ArtifactConstant.ROLE_PREFIX_USER + repositoryName);

        return managerRoleResponse.isSuccess() && developerRoleResponse.isSuccess() && userRoleResponse.isSuccess();
    }

    /**
     * 刪除用戶-包括删除用户实例及删除用户表数据
     *
     * @param artifactType
     * @param artifactUuid
     * @return
     */
    private boolean deleteUserInstanceAndInfo(ArtifactToolEnum.ArtifactTypeEnum artifactType, String artifactUuid) {
        List<ArtifactUser> artifactUserList = artifactUserDomainService.list(ArtifactUserQuery.builder().artifactUuid(artifactUuid).build());
        instanceUserService.deleteUserOfRepository(artifactType, artifactUserList);
        artifactUserDomainService.deleteByArtifactUuid(artifactUuid);
        return true;
    }

    /**
     * 创建仓库webhook能力
     *
     * @param hostedInstanceRepositoryName
     * @param artifactUuid
     * @return
     */
    private boolean createNexusRepositoryCapability(String hostedInstanceRepositoryName, String artifactUuid) {
        CreateWebhookRepositoryRequest createWebhookRepositoryRequest = new CreateWebhookRepositoryRequest();
        CreateWebhookRepositoryRequest.PropertiesData properties = createWebhookRepositoryRequest.getData().get(0).getProperties();
        properties.setUrl(nexus3V1WebhookRepositoryLocalService);
        properties.setRepository(hostedInstanceRepositoryName);
        properties.setSecret("");
        CreateWebhookRepositoryResponse capability = webhookRepositoryCapabilityService.createCapability(createWebhookRepositoryRequest);
        Optional.ofNullable(capability).flatMap(value -> Optional.ofNullable(value.getResult())).ifPresent(result -> {
            if (Boolean.TRUE.equals(result.getSuccess())) {
                Optional.ofNullable(result.getData()).ifPresent(data -> artifactAttributeDomainService.updateWebhookInfo(artifactUuid, data.getTypeId(), data.getId()));
            }
        });
        return true;
    }

    /**
     * 删除仓库webhook能力
     *
     * @param artifactUuid
     * @param webhookId
     * @return
     */
    private boolean removeRepositoryCapability(String artifactUuid, String webhookId) {
        RemoveWebhookRepositoryRequest removeWebhookRepositoryRequest = new RemoveWebhookRepositoryRequest();
        removeWebhookRepositoryRequest.getData().add(webhookId);
        webhookRepositoryCapabilityService.removeCapability(removeWebhookRepositoryRequest);

        artifactAttributeDomainService.updateWebhookInfoToNull(artifactUuid);
        return true;
    }

    /**
     * 创建Nexus3用户角色权限
     *
     * @param repositoryPrivilegesPrefix
     * @param instanceRepositoryName
     * @param hostedInstanceRepositoryName
     * @param groupInstanceRepositoryName
     * @return
     */
    private boolean createNexusUserRolePrivilege(String repositoryPrivilegesPrefix, String instanceRepositoryName, String hostedInstanceRepositoryName, String groupInstanceRepositoryName) {
        // 创建仓库角色-管理员
        CreateRoleRequest managerRoleRequest = new CreateRoleRequest();
        managerRoleRequest.setId(ArtifactConstant.ROLE_PREFIX_MANAGER + instanceRepositoryName);
        managerRoleRequest.setName(managerRoleRequest.getId());
        managerRoleRequest.setDescription(managerRoleRequest.getId());
        List<String> managerPrivilegeList = new ArrayList<String>(Arrays.asList(repositoryPrivilegesPrefix + hostedInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_ALL));
        if (StrUtil.isNotBlank(groupInstanceRepositoryName)) {
            managerPrivilegeList.add(repositoryPrivilegesPrefix + groupInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_ALL);
        }
        managerRoleRequest.setPrivileges(managerPrivilegeList);
        ApiResponseXO<CreateRoleResponse> managerRoleResponse = securityRoleService.createRole(managerRoleRequest);

        // 创建仓库角色-开发人员
        CreateRoleRequest developerRoleRequest = new CreateRoleRequest();
        developerRoleRequest.setId(ArtifactConstant.ROLE_PREFIX_DEVELOPER + instanceRepositoryName);
        developerRoleRequest.setName(developerRoleRequest.getId());
        developerRoleRequest.setDescription(developerRoleRequest.getId());
        List<String> developerPrivilegeList = new ArrayList<String>(Arrays.asList(
                repositoryPrivilegesPrefix + hostedInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_BROWSE,
                repositoryPrivilegesPrefix + hostedInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_READ,
                repositoryPrivilegesPrefix + hostedInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_EDIT,
                repositoryPrivilegesPrefix + hostedInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_ADD));
        if (StrUtil.isNotBlank(groupInstanceRepositoryName)) {
            developerPrivilegeList.add(repositoryPrivilegesPrefix + groupInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_BROWSE);
            developerPrivilegeList.add(repositoryPrivilegesPrefix + groupInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_READ);
            developerPrivilegeList.add(repositoryPrivilegesPrefix + groupInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_EDIT);
            developerPrivilegeList.add(repositoryPrivilegesPrefix + groupInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_ADD);
        }
        developerRoleRequest.setPrivileges(developerPrivilegeList);
        ApiResponseXO<CreateRoleResponse> developerRoleResponse = securityRoleService.createRole(developerRoleRequest);

        // 创建仓库角色-普通用户
        CreateRoleRequest userRoleRequest = new CreateRoleRequest();
        userRoleRequest.setId(ArtifactConstant.ROLE_PREFIX_USER + instanceRepositoryName);
        userRoleRequest.setName(userRoleRequest.getId());
        userRoleRequest.setDescription(userRoleRequest.getId());
        List<String> userPrivilegeList = new ArrayList<String>(Arrays.asList(
                repositoryPrivilegesPrefix + hostedInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_BROWSE,
                repositoryPrivilegesPrefix + hostedInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_READ));
        if (StrUtil.isNotBlank(groupInstanceRepositoryName)) {
            userPrivilegeList.add(repositoryPrivilegesPrefix + groupInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_BROWSE);
            userPrivilegeList.add(repositoryPrivilegesPrefix + groupInstanceRepositoryName + ArtifactConstant.NEXUS3_PRIVILEGES_SUFFIX_READ);
        }
        userRoleRequest.setPrivileges(userPrivilegeList);
        ApiResponseXO<CreateRoleResponse> userRoleResponse = securityRoleService.createRole(userRoleRequest);

        return managerRoleResponse.isSuccess() && developerRoleResponse.isSuccess() && userRoleResponse.isSuccess();
    }

}
